#include "StdAfx.h"
#include "ServerPI.h"

#include "Log.h"
#include "Utils.h"

namespace ftp
{

ServerPI::ServerPI(std::auto_ptr<IChannel> channel, FileSystem* fileSystem)
	: m_channel(channel)
	, m_workingDir("/")
	, m_fileSystem(fileSystem)
	, m_disconnected(false)
{
	m_channel->setSync(this);

	const char str[] = "200 OK"; //welcoming
	m_channel->asyncWrite(str, sizeof(str));
	m_channel->asyncRead();
}

ServerPI::~ServerPI()
{
	m_channel->setSync(nullptr);
}

void ServerPI::onBytesRead(bool ok, const char* bytes, size_t bytesSize)
{
	if (!ok)
	{
		LOG() << "ServerPI finished " << std::endl;
		m_disconnected = true;
		return;
	}

	std::string command;
	std::string argument;
	bool got = utils::getCommandNameAndArgument(std::string(bytes, bytesSize), &command, &argument);
	if (!got)
	{
		//TODO: asyncWrite error
		LOG() << "Can't parse" << std::endl; 
		return;
	}

	LOG() << command << ' ' << argument << std::endl; 

	if (command == "USER")
	{
		handleUserCommand(argument);
	}
	else if (command == "TYPE")
	{
		handleTypeCommand(argument);
	}
	else if (command == "PWD")
	{
		handlePwdCommand(argument);
	}
	else if (command == "LIST")
	{
		handleListCommand(argument);
	}
	else if (command == "PORT")
	{
		handlePortCommand(argument);
	}
	else if (command == "PASV")
	{
		handlePasvCommand(argument);
	}
	else 
	{
		std::string response = utils::makeCommonResponse(200, "OK");
		m_channel->asyncWrite(response.data(), response.size());
	}

	m_channel->asyncRead();
}

void ServerPI::onBytesWrote(bool ok)
{
	if (!ok)
	{
		LOG() << "ServerPI finished " << std::endl;
		m_disconnected = true;
	}
}

// private:

void ServerPI::handleUserCommand(const std::string& arg)
{
	std::string response = utils::makeCommonResponse(200, "OK");
	m_channel->asyncWrite(response.data(), response.size());
}

void ServerPI::handlePwdCommand(const std::string& arg)
{
	std::string response = utils::makePwdResponse(257, m_workingDir, "OK");
	m_channel->asyncWrite(response.data(), response.size());
}

void ServerPI::handleListCommand(const std::string& arg)
{
	std::string response = utils::makeCommonResponse(200, "OK");
	m_channel->asyncWrite(response.data(), response.size());

}
	
void ServerPI::handlePortCommand(const std::string& arg)
{
	std::string response = utils::makeCommonResponse(200, "OK");
	m_channel->asyncWrite(response.data(), response.size());
}

void ServerPI::handlePasvCommand(const std::string& arg)
{
	std::string response = utils::makePasvResponse(227, "127.0.0.1", 50001, "Ok");
	m_channel->asyncWrite(response.data(), response.size());
}

void ServerPI::handleTypeCommand(const std::string& arg)
{
	if (arg == "I")
		m_dataType = kImageDataType;
	else if (arg == "A")
		m_dataType = kAsciiDataType;
	else if (arg == "E")
		m_dataType = kEbicdicDataType;
	else if (arg == "L")
		m_dataType = kLocalDataType;

	std::string response = utils::makeCommonResponse(200, "OK");
	m_channel->asyncWrite(response.data(), response.size());
}

} //ftp
